home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 19 / CU Amiga Magazine's Super CD-ROM 19 (1998)(EMAP Images)(GB)[!][issue 1998-02].iso / CUCD / Online / NNTPd / server / access.c < prev    next >
Encoding:
C/C++ Source or Header  |  2002-12-03  |  6.5 KB  |  284 lines

  1. #ifndef lint
  2. static char    sccsid[] = "@(#)$Id: access.c,v 1.28 1994/12/03 21:54:30 sob Exp sob $";
  3. #endif
  4.  
  5. #include "common.h"
  6. #if defined(EXCELAN) || defined(TLI)
  7. #include <netinet/in.h>
  8. #ifdef TLI
  9. #include <netdb.h>
  10. #endif
  11. #endif
  12. #include <sys/socket.h>
  13.  
  14. #define    SNETMATCH    1
  15. #define    NETMATCH    2
  16.  
  17. /*
  18.  * host_access -- determine if the client has permission to
  19.  * read, transfer, and/or post news.  read->transfer.
  20.  * We switch on socket family so as to isolate network dependent code.
  21.  *
  22.  *    Parameters:    "canread" is a pointer to storage for
  23.  *            an integer, which we set to 1 if the
  24.  *            client can read news, 0 otherwise.
  25.  *
  26.  *            "canpost" is a pointer to storage for
  27.  *            an integer,which we set to 1 if the
  28.  *            client can post news, 0 otherwise.
  29.  *
  30.  *            "canxfer" is a pointer to storage for
  31.  *            an integer,which we set to 1 if the
  32.  *            client can transfer news, 0 otherwise.
  33.  *
  34.  *            "gdlist" is a comma separated list of
  35.  *            newsgroups/distributions which the client
  36.  *            can access.
  37.  *
  38.  *    Returns:    Nothing.
  39.  *
  40.  *    Side effects:    None.
  41.  */
  42.  
  43. #ifdef EXCELAN
  44. extern struct sockaddr_in current_peer;
  45. #endif
  46.  
  47. #ifdef TLI
  48. extern char **Argv;
  49. extern struct hostent *gethostbyname();
  50. #endif
  51.  
  52. #ifdef AUTH
  53. extern    int Needauth;
  54. #endif /* AUTH */
  55.  
  56. void
  57. host_access(canread, canpost, canxfer, gdlist)
  58.     int        *canread, *canpost, *canxfer;
  59.     char        *gdlist;
  60. {
  61.     int        sockt;
  62.     int        length;
  63.     struct sockaddr    sa;
  64. #ifdef TLI
  65.     struct sockaddr_in *sin = (struct sockaddr_in *) &sa;
  66.     struct hostent    *hp;
  67.     int        argcnt = 0;
  68. #endif
  69.     int        match = 0;
  70.     int        count;
  71.     char        hostornet[MAXHOSTNAMELEN];
  72.     char        host_name[MAXHOSTNAMELEN];
  73.     char        net_name[MAXHOSTNAMELEN];
  74.     char        snet_name[MAXHOSTNAMELEN];
  75.     char        readperm[MAXBUFLEN];
  76.     char        postperm[MAXBUFLEN];
  77.     char        groups[MAXBUFLEN];
  78.     char        line[MAXBUFLEN];
  79.     register char    *cp;
  80.     register FILE    *acs_fp;
  81.  
  82.     gdlist[0] = '\0';
  83.  
  84. #ifdef NO_ACCESS_CHECK                /* for special debugging */
  85.     *canread = *canpost = *canxfer = 1;
  86.     return;
  87. #endif
  88.  
  89.     *canread = *canpost = *canxfer = 0;
  90.  
  91.     sockt = fileno(stdin);
  92.     length = sizeof (sa);
  93.  
  94. #ifdef TLI
  95.     if (t_getpeername(sockt, &sa, &length) < 0) {
  96.         if (isatty(sockt)) {
  97.             (void) strcpy(hostname, "stdin");
  98.             *canread = 1;
  99.         } else {
  100. #ifdef SYSLOG
  101.             syslog(LOG_ERR, "host_access: getpeername: %m");
  102. #endif
  103.             (void) strcpy(hostname, "unknown");
  104.         }
  105.         return;
  106.     }
  107.  
  108. #else /* !TLI */
  109.  
  110. #ifdef EXCELAN
  111.     if (raddr(current_peer.sin_addr) == NULL) {
  112. #else
  113.     if (getpeername(sockt, &sa, &length) < 0) {
  114. #endif
  115.         if (isatty(sockt)) {
  116.             (void) strcpy(hostname, "stdin");
  117.             *canread = 1;
  118.         } else {
  119. #ifdef SYSLOG
  120.             syslog(LOG_ERR, "host_access: getpeername: %m");
  121. #endif
  122.             (void) strcpy(hostname, "unknown");
  123.         }
  124.         return;
  125.     }
  126. #ifdef EXCELAN
  127.     else bcopy(¤t_peer,&sa,length);
  128. #endif
  129. #endif /* !TLI */
  130.  
  131.     switch (sa.sa_family) {
  132.     case AF_INET:
  133.         inet_netnames(sockt, &sa, net_name, snet_name, host_name);
  134.         break;
  135.  
  136. #ifdef DECNET
  137.     case AF_DECnet:
  138.         dnet_netnames(sockt, &sa, net_name, snet_name, host_name);
  139.         break;
  140. #endif
  141.  
  142.     default:
  143. #ifdef SYSLOG
  144.         syslog(LOG_ERR, "unknown address family %ld", sa.sa_family);
  145. #endif
  146.         return;
  147.     };
  148.  
  149.     /* Normalize host name to lower case */
  150.  
  151.     for (cp = host_name; *cp; cp++)
  152.         if (isupper(*cp))
  153.             *cp = tolower(*cp);
  154.  
  155. #ifdef LOG
  156.     syslog(LOG_INFO, "%s connect\n", host_name);
  157. #endif
  158.     (void) strcpy(hostname, host_name);
  159.  
  160.     /*
  161.      * We now we have host_name, snet_name, and net_name.
  162.      * Our strategy at this point is:
  163.      *
  164.      * for each line, get the first word
  165.      *
  166.      *    If it matches "host_name", we have a direct
  167.      *        match; parse and return.
  168.      *
  169.      *    If it matches "snet_name", we have a subnet match;
  170.      *        parse and set flags.
  171.      *
  172.      *    If it matches "net_name", we have a net match;
  173.      *        parse and set flags.
  174.      *
  175.      *    If it matches the literal "default", note we have
  176.      *        a net match; parse.
  177.      */
  178.  
  179. #if defined(DEBUG) && defined(SYSLOG)
  180.     if (debug)
  181.         syslog(LOG_DEBUG,
  182.             "host_access(): host_name=%s, snet_name=%s, net_name=%s",
  183.             host_name ? host_name : "NIL",
  184.             snet_name ? snet_name : "NIL",
  185.             net_name ? net_name : "NIL");
  186. #endif
  187.  
  188.     acs_fp = fopen(accessfile, "r");
  189.     if (acs_fp == NULL) {
  190. #ifdef SYSLOG
  191.         syslog(LOG_ERR, "access: fopen %s: %m", accessfile);
  192. #endif
  193.         return;
  194.     }
  195.  
  196.     while (fgets(line, sizeof(line), acs_fp) != NULL) {
  197.         if ((cp = index(line, '\n')) != NULL)
  198.             *cp = '\0';
  199.         if ((cp = index(line, '#')) != NULL)
  200.             *cp = '\0';
  201.         if (*line == '\0')
  202.             continue;
  203.  
  204.         count = sscanf(line, "%s %s %s %s",
  205.                 hostornet, readperm, postperm, groups);
  206.  
  207.         if (count < 4) {
  208.             if (count < 3)
  209.                 continue;
  210.             groups[0] = '\0';    /* No groups specified */
  211.         }
  212. #if defined(DEBUG) && defined(SYSLOG)
  213.     if (debug)
  214.         syslog(LOG_DEBUG,
  215.             "host_access(): hostornet=%s, readperm=%s, postperm=%s, groups=%s",
  216.             hostornet ? hostornet : "NIL",
  217.             readperm ? readperm : "NIL",
  218.             postperm ? postperm : "NIL",
  219.             groups ? groups : "NIL");
  220. #endif
  221.  
  222. #ifdef DOMAINMATCH
  223.         for (cp = hostornet; *cp; cp++)
  224.             if (isupper(*cp))
  225.                 *cp = tolower(*cp);
  226.         if (wildmat(host_name, hostornet)) {
  227. #else
  228.         if (!strcasecmp(hostornet, host_name)) {
  229. #endif
  230.             *canread = (readperm[0] == 'r' || readperm[0] == 'R');
  231.             *canxfer = (readperm[0] == 'X' || readperm[0] == 'x');
  232.             if (readperm[0] == 'B' || readperm[0] == 'b')
  233.                 *canxfer = *canread = 1;
  234.             *canpost = (postperm[0] == 'p' || postperm[0] == 'P');
  235.             (void) strcpy(gdlist, groups);
  236.             break;
  237.         }
  238.  
  239.         if (*snet_name && !strcasecmp(hostornet, snet_name)) {
  240.             match = SNETMATCH;
  241.             *canread = (readperm[0] == 'r' || readperm[0] == 'R');
  242.             *canxfer = (readperm[0] == 'X' || readperm[0] == 'x');
  243.             if (readperm[0] == 'B' || readperm[0] == 'b')
  244.                 *canxfer = *canread = 1;
  245.             *canpost = (postperm[0] == 'p' || postperm[0] == 'P');
  246.             (void) strcpy(gdlist, groups);
  247.         }
  248.  
  249.         if (match != SNETMATCH && (!strcasecmp(hostornet, net_name) ||
  250.             !strcasecmp(hostornet, "default"))) {
  251.             match = NETMATCH;
  252.             *canread = (readperm[0] == 'r' || readperm[0] == 'R');
  253.             *canxfer = (readperm[0] == 'X' || readperm[0] == 'x');
  254.             if (readperm[0] == 'B' || readperm[0] == 'b')
  255.                 *canxfer = *canread = 1;
  256.             *canpost = (postperm[0] == 'p' || postperm[0] == 'P');
  257.             (void) strcpy(gdlist, groups);
  258.         }
  259.     }
  260. /*
  261.  * The access check expects there to be spaces between the group names.
  262.  * In the access file, there are commas between the groupnames.
  263.  * Here, we change the commas to spaces.
  264.  */
  265.          {
  266.        char *pointer=gdlist;
  267.        
  268.        while (*pointer)
  269.          {
  270.            if (*pointer == ',') *pointer=' ';
  271.            pointer++;
  272.          }
  273.      }
  274.  
  275.     (void) fclose(acs_fp);
  276.  
  277. #ifdef AUTH
  278.     Needauth = 0;
  279.     /* do we require a userid and password for this guy? */
  280.     if (isupper(readperm[0]) || isupper(postperm[0]))
  281.         Needauth = 1;
  282. #endif /* AUTH */
  283. }
  284.